home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 5
/
Aminet 5 - March 1995.iso
/
Aminet
/
gfx
/
show
/
amipeg04.lha
/
aMiPEG_0.4
/
parseblock.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-22
|
5KB
|
207 lines
/*
* This source handles parsing and supervises decoding of the blocks and
* passes the decoded data to the idct.
*/
#define NO_SANITY_CHECKS
#include "video.h"
#include "proto.h"
#include "decoders.h"
#define static
/* External declarations. */
extern int zigzag_direct[];
/*
*--------------------------------------------------------------
*
* ParseReconBlock --
*
* Parse values for block structure from bitstream.
* n is an indication of the position of the block within
* the macroblock (i.e. 0-5) and indicates the type of
* block (i.e. luminance or chrominance). Reconstructs
* coefficients from values parsed and puts in
* block.dct_recon array in vid stream structure.
* sparseFlag is set when the block contains only one
* coeffictient and is used by the IDCT.
*
* Results:
*
*
* Side effects:
* Bit stream irreversibly parsed.
*
*--------------------------------------------------------------
*/
#define DCT_recon blockPtr->dct_recon
#define DCT_dc_y_past blockPtr->dct_dc_y_past
#define DCT_dc_cr_past blockPtr->dct_dc_cr_past
#define DCT_dc_cb_past blockPtr->dct_dc_cb_past
void ParseReconBlock(int n)
{
Block *blockPtr = &curVidStream->block;
int diff, level, run, pos, coeff, qscale;
short int *reconptr=DCT_recon[0];
unsigned short *iqmatrixptr;
if (bufLength < 100) correct_underflow();
clear64words(reconptr=DCT_recon[0]);
if (curVidStream->mblock.mb_intra) {
if (n < 4) { /* Get the luminance bits. */
/* Parse and decode size of first coefficient and itself. */
DecodeDCTDCSizeLum(diff);
coeff = diff << 3;
if (n == 0) {
if (curVidStream->mblock.mb_address - curVidStream->mblock.past_intra_addr > 1)
coeff += 1024;
else coeff += DCT_dc_y_past;
} else
coeff += DCT_dc_y_past;
DCT_dc_y_past = coeff;
} else {
/* Parse and decode size of first coefficient and itself. */
DecodeDCTDCSizeChrom(diff);
coeff = diff << 3;
if (n == 4) {
if (curVidStream->mblock.mb_address - curVidStream->mblock.past_intra_addr > 1)
coeff += 1024;
else
coeff += DCT_dc_cr_past;
DCT_dc_cr_past = coeff;
} else {
if (curVidStream->mblock.mb_address - curVidStream->mblock.past_intra_addr > 1)
coeff += 1024;
else
coeff += DCT_dc_cb_past;
DCT_dc_cb_past = coeff;
}
}
*reconptr = coeff;
if (curVidStream->picture.code_type != 4) {
recon_intra(curVidStream->intra_quant_matrix_ptr[curVidStream->slice.quant_scale], reconptr);
}
else
j_rev_dct(reconptr);
} else { /* not an intra-frame */
qscale = curVidStream->slice.quant_scale;
DecodeDCTCoeffFirst(run, level);
pos = zigzag_direct[run];
if (curVidStream->non_intra_default)
{
qscale <<= 4;
reconptr[pos] = ((short)level * (short)qscale) >> 3;
if (curVidStream->picture.code_type != 4) {
recon_nonintra(qscale, run, reconptr);
}
else
j_rev_dct(reconptr);
} else {
iqmatrixptr = curVidStream->non_intra_quant_matrix_ptr[qscale];
reconptr[pos] = ((short)level * iqmatrixptr[run]) >> 3;
if (curVidStream->picture.code_type != 4) {
recon_non2intra(run, iqmatrixptr, reconptr);
}
else
j_rev_dct(reconptr); // eventually, the flush(2) must be applied here, too ? hmmm
}
}
}
#undef DCT_recon
#undef DCT_dc_y_past
#undef DCT_dc_cr_past
#undef DCT_dc_cb_past
/*
*--------------------------------------------------------------
*
* ParseAwayBlock --
*
* Parses off block values, throwing them away.
* Used with grayscale dithering.
*
* Results:
* None.
*
* Side effects:
* None.
*
* To do:
* Move to sutils.s !!
*
*--------------------------------------------------------------
*/
void ParseAwayBlock(int n)
{
unsigned int diff, run;
int level;
if (bufLength < 100) correct_underflow();
if (curVidStream->mblock.mb_intra) {
/* If the block is a luminance block... */
if (n < 4) {
/* Parse and decode size of first coefficient and itself. */
DecodeDCTDCSizeLum(diff);
}
/* Otherwise, block is chrominance block... */
else {
/* Parse and decode size of first coefficient and itself. */
DecodeDCTDCSizeChrom(diff);
}
}
/* Otherwise, block is not intracoded... */
else {
/* Decode and set first coefficient. */
DecodeDCTCoeffFirst(run, level);
}
/* If picture is not D type (i.e. I, P, or B)... */
if (curVidStream->picture.code_type != 4) {
/* While end of macroblock has not been reached... */
do {
DecodeDCTCoeffNext(run, level); /* Get the dct_coeff_next */
} while (run != END_OF_BLOCK);
/* End_of_block */
flush_bits(2);
}
}